package v1

import (
	"gateway-api/controllers"
	"gateway-api/tools"
	"strconv"
	"strings"
	"time"

	pbAccount "gateway-api/proto/account"
	"gateway-api/proto/params"
	pbParams "gateway-api/proto/params"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

/*
 +----------------------------------------------------------------------
 + Title        : AccountController
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2020-11-23
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 账户控制层
 +----------------------------------------------------------------------
*/
type AccountController struct {
	controllers.BaseController
}

/**
 * 登录
 *
 * @param string username ---------------------------------必传,用户名
 * @param string password ---------------------------------必传,密码
 * @param string captcha ----------------------------------必传,验证码
 * @param string captcha_id -------------------------------必传,验证码ID
 * @return Json
 * @author huwl
 */
func (control AccountController) Login(ctx *gin.Context) {
	username := ctx.DefaultPostForm("username", "")
	password := ctx.DefaultPostForm("password", "")
	// captcha := ctx.DefaultPostForm("captcha", "")
	// captchaId := ctx.DefaultPostForm("captcha_id", "")

	if username == "" {
		control.BaseError(ctx, control.WithMessage("请输入用户名"))
		return
	}
	if password == "" {
		control.BaseError(ctx, control.WithMessage("请输入密码"))
		return
	}

	//base64Captcha版
	// b := tools.ValidateCaptcha(captchaId, captcha)
	//dchest版
	// b := tools.VerifyCaptcha(ctx, captcha)
	// if !b {
	// 	control.BaseError(ctx, "验证码错误")
	// 	return
	// }

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	result, err := accountSrvClient.Row(ctx, &pbAccount.QueryAccountRequest{
		Username: username,
		Status:   "1",
		IsCash:   "all",
	})
	if err != nil {
		control.BaseError(ctx, control.WithGrpcError(err))
		return
	}
	if !tools.CompareBcrypt(result.Account.Password, password) {
		control.BaseError(ctx, control.WithMessage("密码错误"))
		return
	}

	token, err := tools.GenerateToken(strconv.Itoa(int(result.Account.Id)))
	if err != nil {
		control.BaseError(ctx, control.WithMessage(err.Error()))
		return
	}

	// 生成refreshToken
	refreshToken := uuid.New().String()
	// 需要将refreshToken存入redis
	ri, err := tools.NewRedisInstance()
	if err != nil {
		control.BaseError(ctx, control.WithMessage(err.Error()))
		return
	}

	err = ri.RedisSet("accountRefreshToken:"+strconv.FormatInt(int64(result.Account.Id), 10), refreshToken, time.Hour*12*10)
	if err != nil {
		control.BaseError(ctx, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(ctx, control.WithData(gin.H{
		"account":           result.Account,
		"roles":             result.Roles,
		"authes":            result.Authes,
		"token":             token,
		"token_expire_time": time.Now().Add(tools.TokenExpireTime).Unix(),
		"refresh_token":     refreshToken,
	}), control.WithMessage("登录成功"))

}

/**
 * 新增账户
 *
 * @param string username ---------------------------------必传,用户名
 * @param string name -------------------------------------非必传,姓名
 * @param string password ---------------------------------必传,密码
 * @param string password_confirmation --------------------必传,确认密码
 * @param string mobile -----------------------------------必传,手机号
 * @param string title ------------------------------------非必传,职位
 * @param string email ------------------------------------必传,邮箱
 * @param string avatar -----------------------------------非必传,头像
 * @param int is_cash -------------------------------------非必传,是否提现
 * @param string note -------------------------------------非必传,备注
 * @return Json
 * @author huwl
 */
func (control AccountController) Add(ctx *gin.Context) {
	username := ctx.DefaultPostForm("username", "")
	password := ctx.DefaultPostForm("password", "")
	password_confirmation := ctx.DefaultPostForm("password_confirmation", "")
	name := ctx.DefaultPostForm("name", "")
	mobile := ctx.DefaultPostForm("mobile", "")
	title := ctx.DefaultPostForm("title", "")
	email := ctx.DefaultPostForm("email", "")
	avatar := ctx.DefaultPostForm("avatar", "")
	is_cash, _ := strconv.ParseInt(ctx.DefaultPostForm("is_cash", ""), 10, 64)
	note := ctx.DefaultPostForm("note", "")

	if username == "" {
		control.BaseError(ctx, control.WithMessage("请输入用户名"))
		return
	}
	if password == "" {
		control.BaseError(ctx, control.WithMessage("请输入密码"))
		return
	}
	if password_confirmation == "" {
		control.BaseError(ctx, control.WithMessage("请输入确认密码"))
		return
	}
	if password != password_confirmation {
		control.BaseError(ctx, control.WithMessage("两次密码不一致"))
		return
	}
	if !tools.CheckMobile(mobile) {
		control.BaseError(ctx, control.WithMessage("请输入格式正确的手机号"))
		return
	}
	if !tools.CheckEmail(email) {
		control.BaseError(ctx, control.WithMessage("请输入格式正确的邮箱"))
		return
	}

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	_, err := accountSrvClient.AddAcount(ctx, &pbAccount.AddAcountRequest{
		Username: username,
		Password: password,
		Name:     name,
		Mobile:   mobile,
		Title:    title,
		Email:    email,
		Avatar:   avatar,
		IsCash:   uint32(is_cash),
		Note:     note,
	})
	if err != nil {
		control.BaseError(ctx, control.WithGrpcError(err))
		return
	}

	control.BaseSuccess(ctx, control.WithData("新增账户成功"))
}

/**
 * 删除账户
 *
 * @param string ids --------------------------------------必传,账户ID,支持多个
 * @return Json
 * @author huwl
 */
func (control AccountController) Delete(ctx *gin.Context) {
	ids := ctx.DefaultPostForm("ids", "")

	if ids == "" {
		control.BaseError(ctx, control.WithMessage("账户ID错误"))
		return
	}

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	_, err := accountSrvClient.DeleteAcount(ctx, &pbParams.IdsRequest{})
	if err != nil {
		control.BaseError(ctx, control.WithGrpcError(err))
		return
	}

	control.BaseSuccess(ctx, control.WithData("删除账户成功"))
}

/**
 * 编辑账户
 *
 * @param int id ------------------------------------------必传,用户名
 * @param string username ---------------------------------非必传,用户名
 * @param string name -------------------------------------非必传,姓名
 * @param string mobile -----------------------------------非必传,手机号
 * @param string email ------------------------------------非必传,邮箱
 * @param string is_cash ----------------------------------非必传,是否现金
 * @param string avatar -----------------------------------非必传,头像
 * @param string note -------------------------------------非必传,备注
 * @return Json
 * @author huwl
 */
func (control AccountController) Edit(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.DefaultPostForm("id", "0"))
	username := ctx.DefaultPostForm("username", "")
	name := ctx.DefaultPostForm("name", "")
	mobile := ctx.DefaultPostForm("mobile", "")
	title := ctx.DefaultPostForm("title", "")
	email := ctx.DefaultPostForm("email", "")
	isCash := ctx.DefaultPostForm("is_cash", "all")
	avatar := ctx.DefaultPostForm("avatar", "")
	note := ctx.DefaultPostForm("note", "")

	if id <= 0 {
		control.BaseError(ctx, control.WithMessage("账户ID错误"))
		return
	}

	params := &pbAccount.EditAcountRequest{Id: uint32(id)}
	if username != "" {
		params.Username = username
	}
	if name != "" {
		params.Name = name
	}
	if mobile != "" {
		if !tools.CheckMobile(mobile) {
			control.BaseError(ctx, control.WithMessage("请输入正确格式的手机号"))
			return
		}

		params.Mobile = mobile
	}
	if title != "" {
		params.Title = title
	}
	if email != "" {
		params.Email = email
	}
	if tools.IsContainStr([]string{"-1", "1"}, isCash) {
		isCash, _ := strconv.Atoi(isCash)
		params.IsCash = int32(isCash)
	}
	if avatar != "" {
		params.Avatar = avatar
	}
	if note != "" {
		params.Note = note
	}

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	result, err := accountSrvClient.EditAcount(ctx, params)
	if err != nil {
		control.BaseError(ctx, control.WithGrpcError(err))
		return
	}

	control.BaseSuccess(ctx, control.WithData(result.Msg))
}

/**
 * 编辑账户状态
 *
 * @param string ids --------------------------------------必传,账户ID,支持多个以英文逗号隔开
 * @param int status --------------------------------------必传,状态
 * @return Json
 * @author huwl
 */
func (control AccountController) EditStatus(ctx *gin.Context) {
	ids := strings.TrimRight(ctx.DefaultQuery("ids", ""), ",")
	status, _ := strconv.Atoi(ctx.DefaultQuery("status", "0"))

	if ids == "" {
		control.BaseError(ctx, control.WithMessage("账户ID错误"))
		return
	}
	if !tools.IsContainNumber([]int{-1, 1}, status) {
		control.BaseError(ctx, control.WithMessage("账户状态错误"))
		return
	}

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	result, err := accountSrvClient.EditAcountStatus(ctx, &params.EditStatusRequest{
		Ids:    ids,
		Status: int64(status),
	})
	if err != nil {
		control.BaseError(ctx, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(ctx, control.WithData(result.Msg))
}

/**
 * 账户列表
 *
 * @param int id ------------------------------------------非必传,账户ID
 * @param string ids --------------------------------------非必传,账户ID,多个以英文逗号隔开
 * @param string username ---------------------------------非必传,用户名
 * @param string name -------------------------------------非必传,姓名
 * @param string mobile -----------------------------------非必传,手机号
 * @param string title ------------------------------------非必传,职位
 * @param string email ------------------------------------非必传,邮箱
 * @param int is_cash -------------------------------------非必传,是否提现现金
 * @param string status -----------------------------------非必传,状态
 * @param string start_create_ime -------------------------必传,开始创建时间
 * @param string end_create_time --------------------------非必传,结束创建时间
 * @param string sort_type --------------------------------非必传,排序方式
 * @param string sort_field -------------------------------非必传,排序字段
 * @param int page_size -----------------------------------非必传,条数
 * @param int page ----------------------------------------非必传,页码
 * @return Json
 * @author huwl
 */
func (control AccountController) List(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.DefaultQuery("id", "0"))
	ids := strings.TrimRight(ctx.DefaultQuery("ids", ""), ",")
	username := ctx.DefaultQuery("username", "")
	name := ctx.DefaultQuery("name", "")
	mobile := ctx.DefaultQuery("mobile", "")
	title := ctx.DefaultQuery("title", "")
	email := ctx.DefaultQuery("email", "")
	isCash := ctx.DefaultQuery("is_cash", "all")
	status := ctx.DefaultQuery("status", "all")
	startCreateTime := ctx.DefaultQuery("start_create_time", "")
	endCreateTime := ctx.DefaultQuery("end_create_time", "")
	sortType := ctx.DefaultQuery("sort", "desc")
	sortField := ctx.DefaultQuery("sort_field", "id")
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))

	// grpcs远程调用账户微服务
	accountSrvClient := pbAccount.NewAccountSrvClient(tools.AccountServiceClientConn)
	result, err := accountSrvClient.AccountList(ctx, &pbAccount.QueryAccountRequest{
		Id:              uint32(id),
		Ids:             ids,
		Username:        username,
		Name:            name,
		Mobile:          mobile,
		Title:           title,
		Email:           email,
		IsCash:          isCash,
		Status:          status,
		StartCreateTime: startCreateTime,
		EndCreateTime:   endCreateTime,
		SortType:        sortType,
		SortField:       sortField,
		PageSize:        uint32(pageSize),
		Page:            uint32(page),
	})
	if err != nil {
		control.BaseError(ctx, control.WithMessage(err.Error()))
		return
	}

	control.BaseSuccess(ctx, control.WithData(gin.H{
		"page":       page,
		"page_total": result.ListResult.PageTotal,
		"total":      result.ListResult.Total,
		"accounts":   result.Accounts,
	}))
}
